package com.kkkk.rest.common.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson2.JSONObject;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class ExcelUtils {
    public static void export(HttpServletResponse response, List list, Class cz, String name) {
        response.setContentType(
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = null;
        try {
            fileName = URLEncoder.encode(name, "UTF-8").replaceAll("\\+", "%20");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        response.setHeader(
                "Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        try {
            EasyExcel.write(response.getOutputStream(), cz).sheet(fileName).doWrite(list);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void export(
            HttpServletResponse response, List list, List<List<String>> head, String name) {
        response.setContentType(
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = null;
        try {
            fileName = URLEncoder.encode(name, "UTF-8").replaceAll("\\+", "%20");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        response.setHeader(
                "Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        try {
            EasyExcel.write(response.getOutputStream()).head(head).sheet(fileName).doWrite(list);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> List<T> readByHttp(MultipartFile file, Class<?> testPageVoClass) {
        try {
            return EasyExcel.read(file.getInputStream()).head(testPageVoClass).sheet().doReadSync();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    public static List<String> readSheetNameByHttp(InputStream file) {
        ExcelReaderBuilder excelReaderBuilder = EasyExcel.read(file);
        ExcelReader excelReader = excelReaderBuilder.build();
        List<ReadSheet> sheets = excelReader.excelExecutor().sheetList();
        List<String> sheetNames = new ArrayList<>();
        for (ReadSheet sheet : sheets) {
            sheetNames.add(sheet.getSheetName());
        }

        return sheetNames;
    }


    // 提取类中所有带有 @ExcelProperty 注解的字段名
    public static List<String> getExcelHeaders(Class<?> clazz) {
        List<String> headers = new ArrayList<>();

        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(ExcelProperty.class)) {
                ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
                headers.add(excelProperty.value()[0]); // 第一个值为列名
            }
        }
        return headers;
    }

    // 提取类中所有带有 @ExcelProperty 注解的字段名
    public static List<List<Object>> getExcelData(List dataList, Class<?> clazz) {
        List<Field> doFields = new ArrayList<>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            // 使私有字段可访问
            field.setAccessible(true);

            if (field.isAnnotationPresent(ExcelProperty.class)) {
                ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
                if (excelProperty != null) {
                    doFields.add(field);
                }
            }
            if (field.getDeclaringClass() == JSONObject.class) {
                doFields.add(field);
            }
        }

        List<List<Object>> data = new ArrayList<>();
        // 通过反射获取 MyExcelData 的所有字段
        for (Object item : dataList) {
            List<Object> rowData = new ArrayList<>();

            // 提取固定字段和动态自定义字段
            try {

                for (Field field : doFields) {
                    Object value = field.get(item);
                    if (value instanceof JSONObject) {
                        JSONObject jsonObject = (JSONObject) value;
                        for (String key : jsonObject.keySet()) {
                            rowData.add(jsonObject.get(key));
                        }
                    } else {
                        rowData.add(value);
                    }
                }

            } catch (IllegalAccessException e) {
                e.printStackTrace(); // 处理异常
            }

            // 将这一行数据添加到最终数据列表中
            data.add(rowData);
        }

        return data;
    }

    // 您可以根据自定义字段追加动态列名
    public static List<String> getHeadersWithCustomFields(
            List<String> headers, Set<String> customFieldKeys) {
        headers.addAll(customFieldKeys); // 动态添加自定义字段名
        return headers;
    }
}
